/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * dataTable.java
 *
 * Created on 8-Oct-2009, 12:05:29 PM
 */
package balony;

import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.URI;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.zip.GZIPOutputStream;
import javax.swing.*;
import javax.swing.RowFilter.Entry;
import javax.swing.RowSorter.SortKey;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.RowSorterEvent;
import javax.swing.event.RowSorterListener;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.*;
import org.apache.commons.math3.stat.inference.TestUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Font;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**
 *
 * @author Barry Young
 */
public class dataTable extends javax.swing.JFrame implements ClipboardOwner {

    public Double minSpotSize;
    public Double maxSpotSize;
    public Double sickCutOff;
    public Double lowCutOff;
    public Double highCutOff;
    public int sickFilterType;
    public HashMap<Integer, TreeSet<String>> excl;
    MyTableModel model;
    TableRowSorter<MyTableModel> sorter;
    MyRowSorterListener mrsl;
    Balony balony;
    public HashSet<ratioPlot> rPs;
    public Double myCtrl[][][][];
    public Double myExp[][][][];
    public String myOrfs[][][];
    public String myGenes[][][];
    public Integer sets, plates, rows, cols;
    public Date fileDate;
    public final int COL_INDEX = 0;
    public final int COL_PLATE = COL_INDEX + 1;
    public final int COL_ROW = COL_PLATE + 1;
    public final int COL_COL = COL_ROW + 1;
    public final int COL_ORF = COL_COL + 1;
    public final int COL_GENE = COL_ORF + 1;
    public final int COL_CTRL = COL_GENE + 1;
    public final int COL_CTRL_SD = COL_CTRL + 1;
    public final int COL_EXP = COL_CTRL_SD + 1;
    public final int COL_EXP_SD = COL_EXP + 1;
    public final int COL_RATIO = COL_EXP_SD + 1;
    public final int COL_RATIO_SD = COL_RATIO + 1;
    public final int COL_SL = COL_RATIO_SD + 1;
    public final int COL_SR = COL_SL + 1;
    public final int COL_DIFF = COL_SR + 1;
    public final int COL_PVAL = COL_DIFF + 1;
    public final int COL_HIT = COL_PVAL + 1;
    public final int COL_EXCLUDE = COL_HIT + 1;
    public final int COL_GINDEX = COL_EXCLUDE + 1;
    public long lastRefresh;
    public String saveFile;
    public HashSet<spotInfo> spotInfos;

    /**
     * Creates new form dataTable
     */
    public dataTable() {
        initComponents();
        rPs = new HashSet<ratioPlot>();
        spotInfos = new HashSet<spotInfo>();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        dataTablePopupMenu = new javax.swing.JPopupMenu();
        spotInfoJMenuItem = new javax.swing.JMenuItem();
        excludeJMenuItem = new javax.swing.JMenuItem();
        includeJMenuItem = new javax.swing.JMenuItem();
        clipCopyJMenu = new javax.swing.JMenu();
        orfsJMenuItem = new javax.swing.JMenuItem();
        genesJMenuItem = new javax.swing.JMenuItem();
        allJMenuItem = new javax.swing.JMenuItem();
        allheadersJMenuItem = new javax.swing.JMenuItem();
        compareJMenu = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        tableJScrollPane = new javax.swing.JScrollPane(analysisTable,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        analysisTable = new javax.swing.JTable() {
            public TableCellRenderer getCellRenderer(int row, int column) {

                TableCellRenderer t=new myRenderer(row,column);
                return t;
            }

        }
        ;
        tableSettingsJPanel = new javax.swing.JPanel();
        highCutOffPanel = new javax.swing.JPanel();
        jLabel4 = new javax.swing.JLabel();
        highCutOffJTextField = new javax.swing.JTextField();
        jLabel7 = new javax.swing.JLabel();
        hcHitsJComboBox = new javax.swing.JComboBox();
        jLabel9 = new javax.swing.JLabel();
        hcpvalJTextField = new javax.swing.JTextField();
        jButton4 = new javax.swing.JButton();
        screenInfoPanel = new javax.swing.JPanel();
        dtNoSets = new javax.swing.JLabel();
        dtScreenName = new javax.swing.JLabel();
        jLabel1 = new javax.swing.JLabel();
        jLabel2 = new javax.swing.JLabel();
        jLabel10 = new javax.swing.JLabel();
        jLabel11 = new javax.swing.JLabel();
        lowCutOffPanel = new javax.swing.JPanel();
        jLabel3 = new javax.swing.JLabel();
        lowCutOffJTextField = new javax.swing.JTextField();
        jLabel6 = new javax.swing.JLabel();
        lcHitsJComboBox = new javax.swing.JComboBox();
        jLabel8 = new javax.swing.JLabel();
        lcpvalJTextField = new javax.swing.JTextField();
        jButton3 = new javax.swing.JButton();
        commandsPanel = new javax.swing.JPanel();
        saveButton = new javax.swing.JButton();
        refreshTableJButton = new javax.swing.JButton();
        showPlotJButton = new javax.swing.JButton();
        exportTableJButton = new javax.swing.JButton();
        filteringPanel = new javax.swing.JPanel();
        linkageJButton = new javax.swing.JButton();
        jLabel5 = new javax.swing.JLabel();
        linkageJTextField = new javax.swing.JTextField();
        hideExcludedJCheckBox = new javax.swing.JCheckBox();
        spotParamsPanel = new javax.swing.JPanel();
        jLabel13 = new javax.swing.JLabel();
        analysisSickFliterComboBox1 = new javax.swing.JComboBox();
        jLabel28 = new javax.swing.JLabel();
        sickCutOffTextField1 = new javax.swing.JTextField();
        jLabel25 = new javax.swing.JLabel();
        minSpotSizeTextField1 = new javax.swing.JTextField();
        jLabel26 = new javax.swing.JLabel();
        maxSpotSizeTextField1 = new javax.swing.JTextField();
        jTextField1 = new javax.swing.JTextField();
        jButton1 = new javax.swing.JButton();
        jLabel12 = new javax.swing.JLabel();
        descFilterJTextField = new javax.swing.JTextField();

        dataTablePopupMenu.addPopupMenuListener(new javax.swing.event.PopupMenuListener() {
            public void popupMenuCanceled(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeInvisible(javax.swing.event.PopupMenuEvent evt) {
            }
            public void popupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {
                dataTablePopupMenuPopupMenuWillBecomeVisible(evt);
            }
        });

        spotInfoJMenuItem.setText("Spot Info");
        spotInfoJMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                spotInfoJMenuItemActionPerformed(evt);
            }
        });
        dataTablePopupMenu.add(spotInfoJMenuItem);

        excludeJMenuItem.setText("Manually exclude spot");
        excludeJMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                excludeJMenuItemActionPerformed(evt);
            }
        });
        dataTablePopupMenu.add(excludeJMenuItem);

        includeJMenuItem.setText("Manually include spot");
        includeJMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                includeJMenuItemActionPerformed(evt);
            }
        });
        dataTablePopupMenu.add(includeJMenuItem);

        clipCopyJMenu.setText("Copy");

        orfsJMenuItem.setText("ORFs");
        orfsJMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                orfsJMenuItemActionPerformed(evt);
            }
        });
        clipCopyJMenu.add(orfsJMenuItem);

        genesJMenuItem.setText("Genes");
        genesJMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                genesJMenuItemActionPerformed(evt);
            }
        });
        clipCopyJMenu.add(genesJMenuItem);

        allJMenuItem.setText("All data");
        allJMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                allJMenuItemActionPerformed(evt);
            }
        });
        clipCopyJMenu.add(allJMenuItem);

        allheadersJMenuItem.setText("All data (with headers)");
        allheadersJMenuItem.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                allheadersJMenuItemActionPerformed(evt);
            }
        });
        clipCopyJMenu.add(allheadersJMenuItem);

        dataTablePopupMenu.add(clipCopyJMenu);

        compareJMenu.setText("Compare with");
        compareJMenu.setEnabled(false);
        compareJMenu.addMenuListener(new javax.swing.event.MenuListener() {
            public void menuCanceled(javax.swing.event.MenuEvent evt) {
            }
            public void menuSelected(javax.swing.event.MenuEvent evt) {
                compareJMenuMenuSelected(evt);
            }
            public void menuDeselected(javax.swing.event.MenuEvent evt) {
            }
        });
        dataTablePopupMenu.add(compareJMenu);

        jMenuItem1.setText("ToneMatrix of ratios (32 rows)");
        jMenuItem1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jMenuItem1ActionPerformed(evt);
            }
        });

        setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosed(java.awt.event.WindowEvent evt) {
                formWindowClosed(evt);
            }
        });

        analysisTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        analysisTable.setIntercellSpacing(new java.awt.Dimension(4, 1));
        analysisTable.setShowHorizontalLines(false);
        analysisTable.setShowVerticalLines(false);
        analysisTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                analysisTableMouseClicked(evt);
            }
        });
        tableJScrollPane.setViewportView(analysisTable);

        highCutOffPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("High cut-off hits"));

        jLabel4.setText("Ratio high cut-off (q):");

        highCutOffJTextField.setText("1.2");

        jLabel7.setText("in sets:");

        hcHitsJComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));

        jLabel9.setText("p<");

        hcpvalJTextField.setText("0.05");

        jButton4.setText("Show");
        jButton4.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton4ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout highCutOffPanelLayout = new javax.swing.GroupLayout(highCutOffPanel);
        highCutOffPanel.setLayout(highCutOffPanelLayout);
        highCutOffPanelLayout.setHorizontalGroup(
            highCutOffPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(highCutOffPanelLayout.createSequentialGroup()
                .addComponent(jLabel4)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(highCutOffJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel7)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(hcHitsJComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel9)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(hcpvalJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jButton4)
                .addContainerGap(50, Short.MAX_VALUE))
        );
        highCutOffPanelLayout.setVerticalGroup(
            highCutOffPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(highCutOffPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel4)
                .addComponent(highCutOffJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel7)
                .addComponent(hcHitsJComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel9)
                .addComponent(hcpvalJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jButton4))
        );

        screenInfoPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Screen Info"));

        dtNoSets.setText("3");

        dtScreenName.setText("Name_of_screen");

        jLabel1.setText("Screen Name:");

        jLabel2.setText("Number of sets:");

        jLabel10.setText("Data scored:");

        jLabel11.setText("- Unknown -");

        javax.swing.GroupLayout screenInfoPanelLayout = new javax.swing.GroupLayout(screenInfoPanel);
        screenInfoPanel.setLayout(screenInfoPanelLayout);
        screenInfoPanelLayout.setHorizontalGroup(
            screenInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(screenInfoPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(screenInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(screenInfoPanelLayout.createSequentialGroup()
                        .addComponent(jLabel1)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(dtScreenName, javax.swing.GroupLayout.PREFERRED_SIZE, 226, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(screenInfoPanelLayout.createSequentialGroup()
                        .addComponent(jLabel2)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(dtNoSets, javax.swing.GroupLayout.PREFERRED_SIZE, 15, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(screenInfoPanelLayout.createSequentialGroup()
                        .addComponent(jLabel10)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(jLabel11)))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        screenInfoPanelLayout.setVerticalGroup(
            screenInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(screenInfoPanelLayout.createSequentialGroup()
                .addGroup(screenInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(dtScreenName)
                    .addComponent(jLabel1))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(screenInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(dtNoSets)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(screenInfoPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel10)
                    .addComponent(jLabel11))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        lowCutOffPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Low cut-off hits"));

        jLabel3.setText("Ratio low cut-off (p):");

        lowCutOffJTextField.setText("0.85");
        lowCutOffJTextField.setPreferredSize(new java.awt.Dimension(22, 20));

        jLabel6.setText("in sets:");

        lcHitsJComboBox.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
        lcHitsJComboBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                lcHitsJComboBoxActionPerformed(evt);
            }
        });

        jLabel8.setText("p<");

        lcpvalJTextField.setText("0.05");

        jButton3.setText("Show");
        jButton3.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton3ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout lowCutOffPanelLayout = new javax.swing.GroupLayout(lowCutOffPanel);
        lowCutOffPanel.setLayout(lowCutOffPanelLayout);
        lowCutOffPanelLayout.setHorizontalGroup(
            lowCutOffPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(lowCutOffPanelLayout.createSequentialGroup()
                .addGap(6, 6, 6)
                .addComponent(jLabel3)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lowCutOffJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel6)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lcHitsJComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jLabel8)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(lcpvalJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jButton3)
                .addContainerGap(48, Short.MAX_VALUE))
        );
        lowCutOffPanelLayout.setVerticalGroup(
            lowCutOffPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(lowCutOffPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                .addComponent(jLabel3)
                .addComponent(lowCutOffJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel6)
                .addComponent(lcHitsJComboBox, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jLabel8)
                .addComponent(lcpvalJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addComponent(jButton3))
        );

        commandsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Misc"));

        saveButton.setText("Save...");
        saveButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                saveButtonActionPerformed(evt);
            }
        });

        refreshTableJButton.setText("Refresh Table");
        refreshTableJButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                refreshTableJButtonActionPerformed(evt);
            }
        });

        showPlotJButton.setText("Show plot");
        showPlotJButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                showPlotJButtonActionPerformed(evt);
            }
        });

        exportTableJButton.setText("Export Table...");
        exportTableJButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                exportTableJButtonActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout commandsPanelLayout = new javax.swing.GroupLayout(commandsPanel);
        commandsPanel.setLayout(commandsPanelLayout);
        commandsPanelLayout.setHorizontalGroup(
            commandsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(commandsPanelLayout.createSequentialGroup()
                .addGroup(commandsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(commandsPanelLayout.createSequentialGroup()
                        .addComponent(refreshTableJButton)
                        .addGap(6, 6, 6)
                        .addComponent(showPlotJButton))
                    .addGroup(commandsPanelLayout.createSequentialGroup()
                        .addComponent(saveButton)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(exportTableJButton)))
                .addContainerGap(15, Short.MAX_VALUE))
        );
        commandsPanelLayout.setVerticalGroup(
            commandsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(commandsPanelLayout.createSequentialGroup()
                .addGroup(commandsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(refreshTableJButton)
                    .addComponent(showPlotJButton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(commandsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(saveButton)
                    .addComponent(exportTableJButton))
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );

        filteringPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Filtering"));

        linkageJButton.setText("Linkage");
        linkageJButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                linkageJButtonActionPerformed(evt);
            }
        });

        jLabel5.setText("Query gene:");

        linkageJTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                linkageJTextFieldKeyReleased(evt);
            }
        });

        hideExcludedJCheckBox.setSelected(true);
        hideExcludedJCheckBox.setText("Hide Excluded Spots");
        hideExcludedJCheckBox.setToolTipText("Select to hide spots that should be excluded from the analysis");
        hideExcludedJCheckBox.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                hideExcludedJCheckBoxActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout filteringPanelLayout = new javax.swing.GroupLayout(filteringPanel);
        filteringPanel.setLayout(filteringPanelLayout);
        filteringPanelLayout.setHorizontalGroup(
            filteringPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, filteringPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(filteringPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(filteringPanelLayout.createSequentialGroup()
                        .addComponent(jLabel5)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(linkageJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 86, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(linkageJButton))
                    .addComponent(hideExcludedJCheckBox))
                .addContainerGap())
        );
        filteringPanelLayout.setVerticalGroup(
            filteringPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(filteringPanelLayout.createSequentialGroup()
                .addGroup(filteringPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jLabel5)
                    .addComponent(linkageJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(linkageJButton, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(hideExcludedJCheckBox)
                .addContainerGap())
        );

        spotParamsPanel.setBorder(javax.swing.BorderFactory.createTitledBorder("Spot Paramaters"));

        jLabel13.setText("Discard data if size of");

        analysisSickFliterComboBox1.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "control spot", "experimental spot", "either spot" }));
        analysisSickFliterComboBox1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                analysisSickFliterComboBox1ActionPerformed(evt);
            }
        });

        jLabel28.setText("is below");

        sickCutOffTextField1.setText("0.2");
        sickCutOffTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                sickCutOffTextField1KeyReleased(evt);
            }
        });

        jLabel25.setText("Min Spot Size");

        minSpotSizeTextField1.setText("0.05");
        minSpotSizeTextField1.setToolTipText("Minimum value to assign to all spots");
        minSpotSizeTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                minSpotSizeTextField1ActionPerformed(evt);
            }
        });
        minSpotSizeTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                minSpotSizeTextField1FocusLost(evt);
            }
        });
        minSpotSizeTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                minSpotSizeTextField1KeyReleased(evt);
            }
        });

        jLabel26.setText("Max Spot Size");

        maxSpotSizeTextField1.setText("100");
        maxSpotSizeTextField1.setToolTipText("Minimum value to assign to all spots");
        maxSpotSizeTextField1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                maxSpotSizeTextField1ActionPerformed(evt);
            }
        });
        maxSpotSizeTextField1.addFocusListener(new java.awt.event.FocusAdapter() {
            public void focusLost(java.awt.event.FocusEvent evt) {
                maxSpotSizeTextField1FocusLost(evt);
            }
        });
        maxSpotSizeTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                maxSpotSizeTextField1KeyReleased(evt);
            }
        });

        javax.swing.GroupLayout spotParamsPanelLayout = new javax.swing.GroupLayout(spotParamsPanel);
        spotParamsPanel.setLayout(spotParamsPanelLayout);
        spotParamsPanelLayout.setHorizontalGroup(
            spotParamsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, spotParamsPanelLayout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(jLabel13)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(analysisSickFliterComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jLabel28)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(sickCutOffTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 38, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap())
            .addGroup(spotParamsPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jLabel25)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(minSpotSizeTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jLabel26)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(maxSpotSizeTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 37, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        spotParamsPanelLayout.setVerticalGroup(
            spotParamsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(spotParamsPanelLayout.createSequentialGroup()
                .addGroup(spotParamsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(sickCutOffTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel28)
                    .addComponent(analysisSickFliterComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jLabel13))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(spotParamsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(spotParamsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel26)
                        .addComponent(maxSpotSizeTextField1))
                    .addGroup(spotParamsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                        .addComponent(jLabel25)
                        .addComponent(minSpotSizeTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addContainerGap())
        );

        jTextField1.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                jTextField1KeyReleased(evt);
            }
        });

        jButton1.setText("Find:");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jLabel12.setText("Desc. filter:");

        descFilterJTextField.setToolTipText("Display only genes that have this text in their description");
        descFilterJTextField.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyReleased(java.awt.event.KeyEvent evt) {
                descFilterJTextFieldKeyReleased(evt);
            }
        });

        javax.swing.GroupLayout tableSettingsJPanelLayout = new javax.swing.GroupLayout(tableSettingsJPanel);
        tableSettingsJPanel.setLayout(tableSettingsJPanelLayout);
        tableSettingsJPanelLayout.setHorizontalGroup(
            tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tableSettingsJPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addGroup(tableSettingsJPanelLayout.createSequentialGroup()
                        .addComponent(screenInfoPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(filteringPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addComponent(commandsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                    .addGroup(tableSettingsJPanelLayout.createSequentialGroup()
                        .addGroup(tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                            .addComponent(lowCutOffPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                            .addComponent(highCutOffPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                        .addGap(12, 12, 12)
                        .addGroup(tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                            .addGroup(tableSettingsJPanelLayout.createSequentialGroup()
                                .addComponent(jButton1)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, 87, javax.swing.GroupLayout.PREFERRED_SIZE)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                                .addComponent(jLabel12)
                                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                                .addComponent(descFilterJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, 110, javax.swing.GroupLayout.PREFERRED_SIZE))
                            .addComponent(spotParamsPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))))
                .addContainerGap(20, Short.MAX_VALUE))
        );
        tableSettingsJPanelLayout.setVerticalGroup(
            tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(tableSettingsJPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addGroup(tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(filteringPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(commandsPanel, 0, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(screenInfoPanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addGap(9, 9, 9)
                .addGroup(tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(tableSettingsJPanelLayout.createSequentialGroup()
                        .addComponent(lowCutOffPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                        .addComponent(highCutOffPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                    .addGroup(tableSettingsJPanelLayout.createSequentialGroup()
                        .addComponent(spotParamsPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(tableSettingsJPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jButton1)
                            .addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addComponent(jLabel12)
                            .addComponent(descFilterJTextField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))))
                .addContainerGap())
        );

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(tableJScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 932, Short.MAX_VALUE)
                    .addComponent(tableSettingsJPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(tableSettingsJPanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(tableJScrollPane, javax.swing.GroupLayout.DEFAULT_SIZE, 472, Short.MAX_VALUE)
                .addContainerGap())
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void formWindowClosed(java.awt.event.WindowEvent evt) {//GEN-FIRST:event_formWindowClosed
        // TODO add your handling code here:
    }//GEN-LAST:event_formWindowClosed

    private void analysisTableMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_analysisTableMouseClicked
        if (evt.getClickCount() == 2) {
            setupSpotInfo(new spotInfo());
        }
    }

    public boolean isLCHit(int row) {
        Hit h;
        h = (Hit) analysisTable.getValueAt(row, COL_HIT);
        if (h.i == 1) {
            return true;
        }
        return false;
    }

    public boolean isHCHit(int row) {
        Hit h;
        h = (Hit) analysisTable.getValueAt(row, COL_HIT);
        if (h.i == 2) {
            return true;
        }
        return false;
    }

    public void updateFilters() {

        List<? extends SortKey> arl = null;
        if (analysisTable.getRowSorter().getSortKeys().size() > 0) {
            arl = analysisTable.getRowSorter().getSortKeys();
        }

        sorter = new TableRowSorter<MyTableModel>(model);

        for (int i = 0; i < analysisTable.getModel().getColumnCount(); i++) {
            sorter.setComparator(i, (Comparator<?>) new EmptyRowComparator(sorter, i));
        }

        RowFilter<MyTableModel, Object> rf = new RowFilter<MyTableModel, Object>() {

            @Override
            public boolean include(Entry<? extends MyTableModel, ? extends Object> entry) {
                TreeSet t = (TreeSet) entry.getValue(COL_EXCLUDE);
                if (t == null || t.isEmpty() || !hideExcludedJCheckBox.isSelected()) {
                    String orf = (String) entry.getValue(COL_ORF);
                    String desc;

                    try {
                        desc = balony.allSGDInfo.get(orf).desc;
                    } catch (Exception e) {
                        desc = "";
                    }

                    String dfilt = descFilterJTextField.getText();
                    if (dfilt != null && !dfilt.isEmpty()) {
                        if (desc.toLowerCase().contains(dfilt.toLowerCase())) {
                            return true;
                        } else {
                            return false;
                        }
                    } else {
                        return true;
                    }
                }



                return false;
            }
        };

        sorter.setRowFilter(rf);
        sorter.addRowSorterListener(mrsl);
        analysisTable.setRowSorter(sorter);
        mrsl.sorterChanged(null);

        if (arl != null) {
            analysisTable.getRowSorter().setSortKeys(arl);
        }
    }

    public void setupSpotInfo(spotInfo sI) {

        sI.setVisible(true);
        sI.setIconImage(balony.balloonImage);
        int row = analysisTable.getSelectedRow();
        spotInfos.add(sI);

        updateSpotInfo(sI, row);
        updatePlots();

    }

    public void updateSpotInfo(spotInfo sI, int row) {

        int p=0;
        int r=0;
        int c=0;
        
        try {
         p = Integer.parseInt(analysisTable.getValueAt(row, COL_PLATE).toString());
         r = Integer.parseInt(analysisTable.getValueAt(row, COL_ROW).toString());
         c = Integer.parseInt(analysisTable.getValueAt(row, COL_COL).toString());
        } catch(Exception e) {
            return;
        }

        sI.currRow = analysisTable.convertRowIndexToModel(row);

        String orf = analysisTable.getValueAt(row, COL_ORF).toString();
        String gene = analysisTable.getValueAt(row, COL_GENE).toString();
        sI.setOrf(orf);
        sI.setGene(gene);
        sI.setPosition(p, r, c);

        int cnt = 0;
        for (int i = 0; i < tableData.length; i++) {
            if (tableData[i][COL_ORF].equals(orf)) {
                cnt++;
            }
        }

        sI.setCopies(cnt);

        sI.balony = balony;
        sI.sourceDataTable = this;
        sI.sourceDT = analysisTable;

        String desc;
        try {
            desc = balony.allSGDInfo.get(orf).desc;
        } catch (Exception e) {
            desc = "N/A";
        }

        StringTokenizer st = new StringTokenizer(desc, " ,;:/\"().?[]{}");

        while (st.hasMoreTokens()) {
            String s = st.nextToken();

            for (String myorf : balony.allSGDInfo.keySet()) {
                if (myorf.toLowerCase().equals(s.toLowerCase())) {
                    desc = desc.replace(s, "<u><font color='blue'>" + s + "</font></u>");
                    sI.jEditorPane1.getDocument().putProperty(s, true);
                }
            }
        }

        st = new StringTokenizer(desc, " ,;:/\"().?[]{}-");

        while (st.hasMoreTokens()) {
            String s = st.nextToken();
            if (s.endsWith("p")) {
                s = s.substring(0, s.length() - 1);
            }

            for (String myorf : balony.allSGDInfo.keySet()) {
                if (balony.allSGDInfo.get(myorf).gene.toLowerCase().equals(s.toLowerCase())) {
                    desc = desc.replace(s, "<u><font color='blue'>" + s + "</font></u>");
                    sI.jEditorPane1.getDocument().putProperty(s, true);
                }
            }
        }

        sI.jEditorPane1.setText("<html><font face = 'Tahoma, Helvetica'>"
                + desc + "</font></html>");

        Double[] ctrlSpots = new Double[sets + 1];
        Double[] expSpots = new Double[sets + 1];

        for (int i = 1; i <= sets; i++) {
            ctrlSpots[i] = myCtrl[i][p][r][c];
            expSpots[i] = myExp[i][p][r][c];
        }

        sI.setupTable(ctrlSpots, expSpots);
        sI.jTable1.setRowSelectionInterval(1, 1);
        sI.updatePanel(sI.jPanel1.getGraphics());
        sI.updatePanel2(sI.jPanel2.getGraphics());

        sI.setTitle(gene + " - " + sI.positionJLabel.getText() + " [" + getTitle() + "]");
        sI.setRank(row + 1);
    }//GEN-LAST:event_analysisTableMouseClicked

    private void linkageJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_linkageJButtonActionPerformed
        doLinkage();
    }

    public void doLinkage() {

        String qgene = linkageJTextField.getText().toLowerCase().trim();
        String orf = "";

        HashSet<String> orfs = new HashSet<String>(balony.allSGDInfo.keySet());

        for (String s : orfs) {
            if (s.toLowerCase().equals(qgene)) {
                orf = s;
            }
        }

        if (orf.length() == 0) {

            for (String s : balony.allSGDInfo.keySet()) {
                String gene = balony.allSGDInfo.get(s).gene;
                if (gene.toLowerCase().equals(qgene)) {
                    orf = s;
                }
            }

            if (orf.isEmpty()) {

                for (String s : balony.allSGDInfo.keySet()) {

                    if (balony.allSGDInfo.get(s).aliases != null) {
                        ArrayList<String> al = balony.allSGDInfo.get(s).aliases;
                        for (int i = 0; i < al.size(); i++) {
                            al.set(i, al.get(i).toLowerCase());
                        }

                        if (al.contains(qgene)) {
                            orf = s;
                        }
                    }
                }
            }
        }

        if (orf.isEmpty()) {
            JOptionPane.showMessageDialog(this, "Cannot find \"" + qgene + "\"",
                    "Unknown ORF", JOptionPane.ERROR_MESSAGE);
            return;
        }

        linkage lnk = new linkage();

        lnk.balony = balony;
        lnk.dt = this;
        lnk.setupLinkage(orf);
        lnk.setIconImage(getIconImage());
        lnk.setVisible(true);

    }//GEN-LAST:event_linkageJButtonActionPerformed

    @SuppressWarnings("unchecked")
    public void setLinkedGenes(ArrayList<String> linkedGenes) {

        if (linkedGenes == null || linkedGenes.isEmpty()) {
            return;
        }

        for (int i = 0; i < tableData.length; i++) {

            String orf = tableData[i][COL_ORF].toString();
            if (linkedGenes.contains(orf)) {
                System.out.println("Linked gene: " + orf);
                TreeSet<String> ex;
                if (tableData[i][COL_EXCLUDE] == null) {
                    ex = new TreeSet<String>();
                } else {
                    ex = (TreeSet<String>) tableData[i][COL_EXCLUDE];
                }
                ex.add("Linked");
                tableData[i][COL_EXCLUDE] = ex;
            }

        }

        updateFilters();

    }

    public Double getRatioByOrf(String orf) {

        ArrayList<Double> d = new ArrayList<Double>();

        for (int i = 0; i < tableData.length; i++) {

            try {
                if (tableData[i][COL_ORF].toString().equals(orf)) {

                    if (!tableData[i][COL_RATIO].equals("") && tableData[i][COL_RATIO] != null) {
                        d.add((Double) tableData[i][COL_RATIO]);
                    }
                }
            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }

        }

        if (d.size() > 0) {
            Double[] dd = d.toArray(new Double[d.size()]);
            return (Balony.mean(dd) != null ? Balony.mean(dd) : 0d);
        }

        return null;
    }
    private void spotInfoJMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_spotInfoJMenuItemActionPerformed
        displayMultipleSpotInfo();
    }

    public void displayMultipleSpotInfo() {
        int[] i = analysisTable.getSelectedRows();

        if (i.length > 20) {
            return;
        }

        int x = 0;
        int y = 0;
        Dimension scr = Toolkit.getDefaultToolkit().getScreenSize();

        for (int r : i) {
            spotInfo sI = new spotInfo();
            sI.setLocation(x, y);
            sI.setVisible(true);
            updateSpotInfo(sI, r);
            x += 24;
            y += 24;
            if (x + sI.getWidth() > scr.width) {
                x = 0;
            }
            if (y + sI.getHeight() > scr.height) {
                y = 0;
            }
        }

    }//GEN-LAST:event_spotInfoJMenuItemActionPerformed

    private void compareJMenuMenuSelected(javax.swing.event.MenuEvent evt) {//GEN-FIRST:event_compareJMenuMenuSelected
    }//GEN-LAST:event_compareJMenuMenuSelected

    private void dataTablePopupMenuPopupMenuWillBecomeVisible(javax.swing.event.PopupMenuEvent evt) {//GEN-FIRST:event_dataTablePopupMenuPopupMenuWillBecomeVisible
    }//GEN-LAST:event_dataTablePopupMenuPopupMenuWillBecomeVisible

    private void hideExcludedJCheckBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_hideExcludedJCheckBoxActionPerformed
        updateFilters();

    }//GEN-LAST:event_hideExcludedJCheckBoxActionPerformed

    @SuppressWarnings({"unchecked", "unchecked"})
    private void excludeJMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_excludeJMenuItemActionPerformed
        int[] i = analysisTable.getSelectedRows();

        for (int ii : i) {
            int row = analysisTable.convertRowIndexToModel(ii);
            TreeSet<String> t;
            if (tableData[row][COL_EXCLUDE] == null) {
                t = new TreeSet<String>();
            } else {
                t = (TreeSet<String>) tableData[row][COL_EXCLUDE];
            }

            t.add("Manual");
            tableData[row][COL_EXCLUDE] = t;
        }

        updateFilters();
    }//GEN-LAST:event_excludeJMenuItemActionPerformed

    @SuppressWarnings("unchecked")
    private void includeJMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_includeJMenuItemActionPerformed
        int[] i = analysisTable.getSelectedRows();

        for (int ii : i) {
            int row = analysisTable.convertRowIndexToModel(ii);

            if (tableData[row][COL_EXCLUDE] != null) {
                TreeSet<String> t;
                t = (TreeSet<String>) tableData[row][COL_EXCLUDE];
                t.remove("Manual");
                if (t.isEmpty()) {
                    t = null;
                }
                tableData[row][COL_EXCLUDE] = t;
            }
        }

        updateFilters();
    }//GEN-LAST:event_includeJMenuItemActionPerformed

    private void saveButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_saveButtonActionPerformed

        // Data to save:
        // Params passed to setupData
        // Double ctrl[][][][], Double exp[][][][], int s, int p,
        //   int r, int c, String[][][] orf, String[][][] genes
        // Exclude column
        // Properties containing variables:
        // High cut-off, low cut-off, screen name, linked gene box


        JFileChooser jfc = new JFileChooser();
        jfc.setFileFilter(new FileNameExtensionFilter("Balony Datatable Files (.bdt)", "bdt"));
        if (saveFile != null && !saveFile.isEmpty()) {
            jfc.setSelectedFile(new File(saveFile));
        }
        int rv = jfc.showSaveDialog(this);

        if (rv == JFileChooser.APPROVE_OPTION) {
            File f = jfc.getSelectedFile();
            String fname = f.getAbsolutePath();
            if (!fname.endsWith(".bdt")) {
                fname = fname + ".bdt";
            }

            saveFile = fname;
            
            if(new File(saveFile).exists()) {
                int n = JOptionPane.showOptionDialog(null,
                        "File already exists. Overwrite?", "Warning!",
                        JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE,
                        null, null, null);
                if (n == JOptionPane.NO_OPTION) {
                    return;
                }
            }

            System.out.println("Saving...");
            ObjectOutputStream oos;
            try {
                oos = new ObjectOutputStream(new GZIPOutputStream(new FileOutputStream(fname)));
                oos.writeObject(myCtrl);
                oos.writeObject(myExp);
                oos.writeObject(sets);
                oos.writeObject(plates);
                oos.writeObject(rows);
                oos.writeObject(cols);
                oos.writeObject(myOrfs);
                oos.writeObject(myGenes);
                oos.writeObject(minSpotSize);
                oos.writeObject(maxSpotSize);
                oos.writeObject(sickCutOff);
                oos.writeObject(lowCutOff);
                oos.writeObject(highCutOff);
                oos.writeObject(getTitle());
                oos.writeObject(saveFile);

                oos.writeObject(dtScreenName.getText());
                oos.writeObject((Boolean) hideExcludedJCheckBox.isSelected());
                oos.writeObject(linkageJTextField.getText());
                oos.writeObject(lowCutOffJTextField.getText());
                oos.writeObject(highCutOffJTextField.getText());
                oos.writeObject(lcHitsJComboBox.getModel());
                oos.writeObject(lcHitsJComboBox.getSelectedItem());
                oos.writeObject(hcHitsJComboBox.getModel());
                oos.writeObject(hcHitsJComboBox.getSelectedItem());
                oos.writeObject(lcpvalJTextField.getText());
                oos.writeObject(hcpvalJTextField.getText());
                oos.writeObject((Integer) analysisSickFliterComboBox1.getSelectedIndex());
                oos.writeObject(sickCutOffTextField1.getText());
                oos.writeObject(minSpotSizeTextField1.getText());
                oos.writeObject(maxSpotSizeTextField1.getText());


//                oos.writeObject(tableData);

                // Exclude column
                excl = new HashMap<Integer, TreeSet<String>>();
                for (int i = 0; i < tableData.length; i++) {
                    @SuppressWarnings("unchecked")
                    TreeSet<String> t = (TreeSet<String>) tableData[i][COL_EXCLUDE];
                    if (t != null && !t.isEmpty()) {
                        excl.put((Integer) i, t);
                    }
                }

                oos.writeObject(excl);
                oos.writeObject(fileDate);
                excl = null;

                // Table Properties

                oos.close();
            } catch (Exception ex) {
                System.out.println(ex.getLocalizedMessage());
            }

        }
        // TODO add your handling code here:
    }//GEN-LAST:event_saveButtonActionPerformed

    private void linkageJTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_linkageJTextFieldKeyReleased
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            doLinkage();
        }
    }//GEN-LAST:event_linkageJTextFieldKeyReleased

    private void analysisSickFliterComboBox1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_analysisSickFliterComboBox1ActionPerformed
        reSetupData();
    }//GEN-LAST:event_analysisSickFliterComboBox1ActionPerformed

    private void sickCutOffTextField1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_sickCutOffTextField1KeyReleased
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            reSetupData();
        }
    }//GEN-LAST:event_sickCutOffTextField1KeyReleased

    private void minSpotSizeTextField1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_minSpotSizeTextField1KeyReleased
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            double tmpmin;
            try {
                tmpmin = Double.parseDouble(minSpotSizeTextField1.getText());
                if (tmpmin != minSpotSize) {
                    reSetupData();
                }
            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }
        }
    }//GEN-LAST:event_minSpotSizeTextField1KeyReleased

    private void refreshTableJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_refreshTableJButtonActionPerformed
        reSetupData();
    }//GEN-LAST:event_refreshTableJButtonActionPerformed

    private void minSpotSizeTextField1FocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_minSpotSizeTextField1FocusLost
        double tmpmin;
        try {
            tmpmin = Double.parseDouble(minSpotSizeTextField1.getText());
            if (tmpmin != minSpotSize) {
                reSetupData();
            }
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }//GEN-LAST:event_minSpotSizeTextField1FocusLost

    private void maxSpotSizeTextField1FocusLost(java.awt.event.FocusEvent evt) {//GEN-FIRST:event_maxSpotSizeTextField1FocusLost
        double tmpmax;
        try {
            tmpmax = Double.parseDouble(maxSpotSizeTextField1.getText());
            if (tmpmax != maxSpotSize) {
                reSetupData();
            }
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }//GEN-LAST:event_maxSpotSizeTextField1FocusLost

    private void maxSpotSizeTextField1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_maxSpotSizeTextField1KeyReleased
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {



            double tmpmax;
            try {
                tmpmax = Double.parseDouble(maxSpotSizeTextField1.getText());
                if (tmpmax != maxSpotSize) {
                    reSetupData();
                }
            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }
        }
    }//GEN-LAST:event_maxSpotSizeTextField1KeyReleased

    private void maxSpotSizeTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_maxSpotSizeTextField1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_maxSpotSizeTextField1ActionPerformed

    private void minSpotSizeTextField1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_minSpotSizeTextField1ActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_minSpotSizeTextField1ActionPerformed

    public void setSortRatioAscending() {
        ArrayList<SortKey> ls = new ArrayList<SortKey>();
        reSetupData();
        ls.add(new SortKey(COL_RATIO, SortOrder.ASCENDING));
        analysisTable.getRowSorter().setSortKeys(ls);
        analysisTable.scrollRectToVisible(analysisTable.getCellRect(0, 0, true));
    }

    private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
        ArrayList<SortKey> ls = new ArrayList<SortKey>();
        reSetupData();
        ls.add(new SortKey(COL_HIT, SortOrder.ASCENDING));
        ls.add(new SortKey(COL_RATIO, SortOrder.ASCENDING));
        analysisTable.getRowSorter().setSortKeys(ls);
        analysisTable.scrollRectToVisible(analysisTable.getCellRect(0, 0, true));
        updateFilters();
    }//GEN-LAST:event_jButton3ActionPerformed

    private void jButton4ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton4ActionPerformed
        ArrayList<SortKey> ls = new ArrayList<SortKey>();
        reSetupData();
        ls.add(new SortKey(COL_HIT, SortOrder.DESCENDING));
        ls.add(new SortKey(COL_RATIO, SortOrder.DESCENDING));
        analysisTable.getRowSorter().setSortKeys(ls);
        analysisTable.scrollRectToVisible(analysisTable.getCellRect(0, 0, true));
        updateFilters();
    }//GEN-LAST:event_jButton4ActionPerformed

    private void showPlotJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_showPlotJButtonActionPerformed
        ratioPlot rP = new ratioPlot();
        rP.dt = this;
        rP.setIconImage(getIconImage());
        rP.setVisible(true);
        rP.setTitle("Ratio Plot: " + getTitle());
        rPs.add(rP);
    }//GEN-LAST:event_showPlotJButtonActionPerformed

    private void lcHitsJComboBoxActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_lcHitsJComboBoxActionPerformed
        // TODO add your handling code here:
    }//GEN-LAST:event_lcHitsJComboBoxActionPerformed

    private void exportTableJButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_exportTableJButtonActionPerformed
        String opts[] = {"Tab-delimited text (raw)", "Excel .xls"
            ,"Excel 2007+ .xlsx"
        };
        int i = JOptionPane.showOptionDialog(this, "Choose output format:",
                "Export Table", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE,
                null, opts, opts[0]);
        if (i == JOptionPane.CLOSED_OPTION) {
            return;
        }

        JFileChooser jfc = new JFileChooser();
        if (i == 0) {
            jfc.setFileFilter(new FileNameExtensionFilter("Tab-delimited text files",
                    "txt"));
            jfc.setSelectedFile(new File(getTitle().concat(".txt")));
        }

        if (i == 1) {
            jfc.setFileFilter(new FileNameExtensionFilter("Excel .xls files",
                    "xls"));
            jfc.setSelectedFile(new File(getTitle().concat(".xls")));
        }

        if (i == 2) {
            jfc.setFileFilter(new FileNameExtensionFilter("Excel .xlsx files",
                    "xlsx"));
            jfc.setSelectedFile(new File(getTitle().concat(".xlsx")));
        }

        int rv = jfc.showSaveDialog(this);
        if (rv == JFileChooser.APPROVE_OPTION) {
            File f = jfc.getSelectedFile();

            try {

                if (i == 0) {
                    BufferedWriter out = new BufferedWriter(new FileWriter(f));
                    for (int k = 0; k < model.columnNames.length; k++) {
                        out.write(model.columnNames[k]);
                        out.write("\t");
                    }
                    out.newLine();
                    for (int j = 0; j < tableData.length; j++) {
                        for (int k = 0; k < model.columnNames.length; k++) {
                            if (tableData[j][k] != null) {
                                out.write(tableData[j][k].toString());
                            }
                            out.write("\t");
                        }
                        out.newLine();
                    }
                    out.close();
                }

                if (i > 0) {

                    Workbook wb;

                    if (i == 1) {
                        wb = new HSSFWorkbook();
                    } else {
                        wb = new XSSFWorkbook();
                    }

                    Sheet sheet = wb.createSheet(getTitle());
                    Row r;
                    CellStyle style;
                    sheet.createFreezePane(0, 1);

                    for (int j = 0; j < tableData.length; j++) {
                        r = sheet.createRow(j + 1);
                        for (int k = 0; k < model.columnNames.length; k++) {

                            if (tableData[j][k] != null) {
                                Cell c = r.createCell(k);

                                if (tableData[j][k] instanceof Integer) {
                                    c.setCellType(Cell.CELL_TYPE_NUMERIC);
                                    int v = ((Integer) tableData[j][k]).intValue();
                                    c.setCellValue(v);
                                } else {
                                    if (tableData[j][k] instanceof Double) {
                                        c.setCellType(Cell.CELL_TYPE_NUMERIC);
                                        double v = ((Double) tableData[j][k]).doubleValue();
                                        c.setCellValue(v);
                                    } else {

                                        c.setCellType(Cell.CELL_TYPE_STRING);
                                        c.setCellValue(tableData[j][k].toString());

                                    }
                                }
                            }
                        }
                    }

                    r = sheet.createRow(0);
                    style = wb.createCellStyle();
                    Font font = wb.createFont();
                    font.setBoldweight(Font.BOLDWEIGHT_BOLD);
                    style.setFont(font);

                    for (int k = 0; k < model.columnNames.length; k++) {
                        Cell c = r.createCell(k);
                        c.setCellType(Cell.CELL_TYPE_STRING);
                        c.setCellStyle(style);
                        c.setCellValue(model.columnNames[k]);
                    }

                    FileOutputStream fos = new FileOutputStream(f);
                    wb.write(fos);
                    fos.close();
                }

            } catch (Exception ex) {
                Logger.getLogger(dataTable.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(this, "File error: ".concat(ex.getLocalizedMessage()),
                        "File Error", JOptionPane.ERROR_MESSAGE);
                return;
            }
            int n = JOptionPane.showOptionDialog(this, "File saved. Open in default application?", "Message",
                    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null,
                    null, null);
            if (n == JOptionPane.YES_OPTION) {
                try {
                    Desktop d = Desktop.getDesktop();
                    d.open(f);
                } catch (IOException e) {
                    System.out.println(e.getLocalizedMessage());
                }
            }
        }


    }//GEN-LAST:event_exportTableJButtonActionPerformed

    private void orfsJMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_orfsJMenuItemActionPerformed
        int[] i = analysisTable.getSelectedRows();
        if (i == null || i.length == 0) {
            return;
        }

        String clip = "";
        for (int j = 0; j < i.length; j++) {
            if (j != 0) {
                clip = clip + "\n";
            }
            int k = analysisTable.convertRowIndexToModel(i[j]);
            String orf = (String) tableData[k][COL_ORF];
            clip = clip + orf;
        }

        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(new StringSelection(clip), this);

    }//GEN-LAST:event_orfsJMenuItemActionPerformed

    private void genesJMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_genesJMenuItemActionPerformed
        int[] i = analysisTable.getSelectedRows();
        if (i == null || i.length == 0) {
            return;
        }

        String clip = "";
        for (int j = 0; j < i.length; j++) {
            if (j != 0) {
                clip = clip + "\n";
            }
            int k = analysisTable.convertRowIndexToModel(i[j]);
            String orf = (String) tableData[k][COL_GENE];
            clip = clip + orf;
        }

        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(new StringSelection(clip), this);

    }//GEN-LAST:event_genesJMenuItemActionPerformed

    private void allJMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allJMenuItemActionPerformed
        int[] i = analysisTable.getSelectedRows();
        if (i == null || i.length == 0) {
            return;
        }

        String clip = "";
        for (int j = 0; j < i.length; j++) {
            if (j != 0) {
                clip = clip + "\n";
            }
            for (int m = 0; m < model.columnNames.length; m++) {
                if (m != 0) {
                    clip = clip + "\t";
                }
                int k = analysisTable.convertRowIndexToModel(i[j]);
                String txt = "";
                if (tableData[k][m] != null) {
                    txt = tableData[k][m].toString();
                }
                clip = clip + txt;
            }
        }

        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(new StringSelection(clip), this);

    }//GEN-LAST:event_allJMenuItemActionPerformed

    private void allheadersJMenuItemActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_allheadersJMenuItemActionPerformed
        int[] i = analysisTable.getSelectedRows();
        if (i == null || i.length == 0) {
            return;
        }

        String clip = "";
        for (int m = 0; m < model.columnNames.length; m++) {
            if (m != 0) {
                clip = clip + "\t";
            }
            String txt = model.columnNames[m];
            clip = clip + txt;
        }

        for (int j = 0; j < i.length; j++) {
            clip = clip + "\n";

            for (int m = 0; m < model.columnNames.length; m++) {
                if (m != 0) {
                    clip = clip + "\t";
                }
                int k = analysisTable.convertRowIndexToModel(i[j]);
                String txt = "";
                if (tableData[k][m] != null) {
                    txt = tableData[k][m].toString();
                }
                clip = clip + txt;
            }
        }

        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(new StringSelection(clip), this);

    }//GEN-LAST:event_allheadersJMenuItemActionPerformed

    private void jMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jMenuItem1ActionPerformed
        StringBuilder sb = new StringBuilder();
        int i = analysisTable.getSelectedRow();
        if (i == -1) {
            i = 0;
        }
        for (int j = i; j < i + 16; j++) {
            if (j != i) {
                sb.append(",");
            }
            Double k = 0d;
            Double l = 0d;
            try {
                k = (Double) analysisTable.getValueAt(j, COL_RATIO);
            } catch (Exception e) {
            }
            try {
                l = (Double) analysisTable.getValueAt(j + 16, COL_RATIO);
            } catch (Exception e) {
            }
            int n1 = (int) (k * 256);
            int n2 = (int) (l * 256);

            if (n1 > 1024) {
                n1 = 1024;
            }

            if (n2 > 1024) {
                n2 = 1024;
            }

            int n = n1 * 2 + n2 * 512;
            sb.append(n);
        }
        System.out.println("ToneMatrix: " + sb.toString());
        Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
        clipboard.setContents(new StringSelection(sb.toString()), this);
        JOptionPane.showMessageDialog(this, "Right click and paste into the Tone Matrix");
        Desktop d = Desktop.getDesktop();
        try {
            d.browse(new URI("http://lab.andre-michelle.com/tonematrix"));
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }

    }//GEN-LAST:event_jMenuItem1ActionPerformed

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
        doFind(jTextField1.getText().toLowerCase());
    }//GEN-LAST:event_jButton1ActionPerformed

    private void jTextField1KeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_jTextField1KeyReleased
        if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
            doFind(jTextField1.getText().toLowerCase());
        }
    }//GEN-LAST:event_jTextField1KeyReleased

    private void descFilterJTextFieldKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_descFilterJTextFieldKeyReleased
        updateFilters();
    }//GEN-LAST:event_descFilterJTextFieldKeyReleased

    public void updatePlots() {
        for (ratioPlot rp : rPs) {
            rp.externRefreshPlot();
        }
    }

    @Override
    public void lostOwnership(Clipboard clipboard, Transferable contents) {
    }

    public class compData {

        Double[] ctrl1;
        Double[] exp1;
        Double[] ctrl2;
        Double[] exp2;
        String orf;
        String gene;

        public void compData() {
        }
    }

    public void doComp(dataTable comp) {
        screenComp sC = new screenComp();
        sC.screen1Label.setText(getTitle());
        sC.screen2Label.setText(comp.getTitle());
        sC.setVisible(true);

        int[] selRows = analysisTable.getSelectedRows();
        HashMap<Integer[], compData> cmp = new HashMap<Integer[], compData>();

        for (int i : selRows) {
            int r = analysisTable.convertRowIndexToModel(i);

            int pl = (Integer) analysisTable.getValueAt(r, COL_PLATE);
            int ro = (Integer) analysisTable.getValueAt(r, COL_ROW);
            int co = (Integer) analysisTable.getValueAt(r, COL_COL);

            Integer[] coord = {(Integer) pl, (Integer) ro, (Integer) co};

            compData cd = new compData();
            cd.ctrl1 = new Double[sets + 1];
            cd.exp1 = new Double[sets + 1];
            cd.ctrl2 = new Double[comp.sets + 1];
            cd.exp2 = new Double[comp.sets + 1];

            cd.orf = (String) analysisTable.getValueAt(r, COL_ORF);
            cd.gene = (String) analysisTable.getValueAt(r, COL_GENE);

            for (int j = 1; j <= sets; j++) {
                cd.ctrl1[j] = myCtrl[j][pl][ro][co];
                cd.exp1[j] = myExp[j][pl][ro][co];
            }

            for (int j = 1; j <= comp.sets; j++) {
                cd.ctrl2[j] = comp.myCtrl[j][pl][ro][co];
                cd.exp2[j] = comp.myExp[j][pl][ro][co];
            }

            cmp.put(coord, cd);

        }

        sC.cmp = cmp;
        sC.displayPlot(sC.jPanel1.getGraphics());

    }

    /**
     * @param args the command line arguments
     */
//    public static void main(String args[]) {
//        java.awt.EventQueue.invokeLater(new Runnable() {
//            public void run() {
//                new dataTable().setVisible(true);
//            }
//        });
//    }
    // Use this to recalculate the table if we change a parameter
    public void reSetupData() {
        @SuppressWarnings("unchecked")
        List<? extends SortKey> arl;
        try {
            if (analysisTable.getRowSorter() != null
                    && analysisTable.getRowSorter().getSortKeys().size() > 0) {
                arl = analysisTable.getRowSorter().getSortKeys();
                setupData(balony, myCtrl, myExp, sets, plates, rows, cols, myOrfs, myGenes);
                analysisTable.getRowSorter().setSortKeys(arl);
            } else {
                setupData(balony, myCtrl, myExp, sets, plates, rows, cols, myOrfs, myGenes);
            }
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }

    public void setupData(Balony b, Double ctrl[][][][], Double exp[][][][], Integer s, Integer p,
            Integer r, Integer c, String[][][] orf, String[][][] genes) {
        balony = b;
        myCtrl = ctrl;
        myExp = exp;
        myOrfs = orf;
        myGenes = genes;
        sets = s;
        plates = p;
        rows = r;
        cols = c;
        Double ratios[] = new Double[plates * rows * cols + 1];

        model = new MyTableModel();
        mrsl = new MyRowSorterListener();

        if (tableData == null) {
            setTableData(new Object[p * r * c][20]);
        }
        dtScreenName.setText(this.getTitle());
        dtNoSets.setText(Integer.toString(s));

        try {
            sickCutOff = Double.parseDouble(sickCutOffTextField1.getText());
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }

        int cnt = 0;
        for (int j = 1; j <= p; j++) {
            for (int k = 1; k <= r; k++) {
                for (int l = 1; l <= c; l++) {
                    Double avc;
                    Double ave;
                    Double sdc;
                    Double sde;
                    String o = orf[j][k][l];

                    Double[] car = new Double[s + 1];
                    Double[] ear = new Double[s + 1];
                    Double[] rar = new Double[s + 1];

                    tableData[cnt][COL_INDEX] = new Integer(cnt + 1);

                    // Filter out sick spots
                    for (int i = 1; i <= s; i++) {

                        if (keepData(ctrl[i][j][k][l], exp[i][j][k][l])) {
                            car[i] = getAdjustedSpotSize(ctrl[i][j][k][l]);
                            ear[i] = getAdjustedSpotSize(exp[i][j][k][l]);
                        }
                    }

                    avc = Balony.mean(car);
                    ave = Balony.mean(ear);

                    if (avc == null) {
                        avc = 0d;
                    }

                    if (ave == null) {
                        ave = 0d;
                    }

                    sdc = Balony.stdev(car);
                    sde = Balony.stdev(ear);

                    tableData[cnt][COL_PLATE] = j;
                    tableData[cnt][COL_ROW] = k;
                    tableData[cnt][COL_COL] = l;

                    // Determine ORF and gene names
                    try {
                        tableData[cnt][COL_ORF] = o;

                        if (genes[j][k][l].length() == 0) {
                            tableData[cnt][COL_GENE] = o;
                        } else {
                            tableData[cnt][COL_GENE] = genes[j][k][l];
                        }
                    } catch (ArrayIndexOutOfBoundsException e) {
                        tableData[cnt][COL_ORF] = "";
                        tableData[cnt][COL_GENE] = "";
                        System.out.println(e.getLocalizedMessage());
                    }

                    // Determine Mean and SD for Ctrl and Exp
                    tableData[cnt][COL_CTRL] = avc;
                    tableData[cnt][COL_CTRL_SD] = sdc;
                    tableData[cnt][COL_EXP] = ave;
                    tableData[cnt][COL_EXP_SD] = sde;

                    if (avc == 0) {
                        tableData[cnt][COL_RATIO] = "";
                    }

                    // Calculate mean ratio
                    int sl = 0;
                    int sr = 0;
                    int scnt = 0;
                    float slr = Float.parseFloat(lowCutOffJTextField.getText());
                    float srr = Float.parseFloat(highCutOffJTextField.getText());

                    for (int i = 1; i <= s; i++) {
                        if (car[i] != null && car[i] != 0) {

                            if (keepData(car[i], ear[i])) {

                                scnt++;
                                rar[i] = ear[i] / car[i];
                                if (rar[i] < slr) {
                                    sl++;
                                }

                                if (rar[i] > srr) {
                                    sr++;
                                }
                            }
                        }
                    }

                    tableData[cnt][COL_RATIO] = Balony.mean(rar);
                    ratios[cnt] = Balony.mean(rar);
                    if (ratios[cnt] == null) {
                        ratios[cnt] = 0d;
                    }

                    tableData[cnt][COL_RATIO_SD] = Balony.stdev(rar);

                    HitPair h = new HitPair();
                    h.a = sl;
                    h.b = scnt;
                    tableData[cnt][COL_SL] = h;

                    h = new HitPair();
                    h.a = sr;
                    h.b = scnt;
                    tableData[cnt][COL_SR] = h;

                    ArrayList<Double> Dsample1 = new ArrayList<Double>();
                    ArrayList<Double> Dsample2 = new ArrayList<Double>();

                    for (int ii = 1; ii <= sets; ii++) {
                        if (car[ii] != null && ear[ii] != null) {
//                        if (car[ii] != null && ear[ii] != null && keepData(car[ii], ear[ii])) {
                            Dsample1.add(car[ii]);
                            Dsample2.add(ear[ii]);
                        }
                    }

                    tableData[cnt][COL_PVAL] = "";

                    double[] sample1;
                    double[] sample2;

                    Double pval = new Double(2d);

                    if (Dsample1.size() > 1) {
                        sample1 = new double[Dsample1.size()];
                        sample2 = new double[Dsample1.size()];

                        for (int ii = 0; ii < sample1.length; ii++) {
                            sample1[ii] = Dsample1.get(ii).doubleValue();
                            sample2[ii] = Dsample2.get(ii).doubleValue();
                        }

                        try {
                            pval = new Double(TestUtils.pairedTTest(sample1, sample2));
                        } catch (Exception ex) {
                            System.out.println(ex.getLocalizedMessage());
                        }

                        if (pval > -1 && pval < 1) {
                            tableData[cnt][COL_PVAL] = pval;
                        }
                    }

                    if (scnt == 0) {
                        tableData[cnt][COL_RATIO] = "";
                        tableData[cnt][COL_RATIO_SD] = "";
                        tableData[cnt][COL_DIFF] = "";
                    }

                    Double lcpval = 1d;
                    Double hcpval = 1d;

                    try {
                        lcpval = Double.parseDouble(lcpvalJTextField.getText());
                        hcpval = Double.parseDouble(hcpvalJTextField.getText());
                    } catch (Exception e) {
                        System.out.println(e.getLocalizedMessage());
                    }

                    Integer lchits = (Integer) lcHitsJComboBox.getSelectedItem();
                    Integer hchits = (Integer) hcHitsJComboBox.getSelectedItem();

                    Hit hit = new Hit();
                    if (sl >= lchits.intValue() && pval < lcpval) {
                        hit.i = 1;
                    } else {
                        if (sr >= hchits.intValue() && pval < hcpval) {
                            hit.i = 2;
                        } else {
                            hit.i = 0;
                        }
                    }

                    tableData[cnt][COL_HIT] = hit;
                    tableData[cnt][COL_DIFF] = ave - avc;
                    tableData[cnt][COL_GINDEX] = 0;

                    try {
                        tableData[cnt][COL_GINDEX] = b.genomeIndex.get(orf[j][k][l]);
                    } catch (Exception e) {
                        System.out.println(e.getLocalizedMessage());
                    }

                    if (tableData[cnt][COL_GINDEX] == null) {

                        try {
                            Integer gI = 0;
                            if (o.startsWith("Y") && o.length() > 6) {
                                int i = Integer.parseInt(o.substring(3, 6));
                                int x = 1;
                                int y = 1;

                                while (x < 10 && gI == 0) {
                                    int z = i + (x * y);
                                    String s1 = "";
                                    if (z < 100) {
                                        s1 = "0";
                                    }
                                    if (z < 10) {
                                        s1 = "00";
                                    }
                                    String s2 = o.substring(0, 3) + s1 + Integer.toString(z) + "C";
                                    String s3 = o.substring(0, 3) + s1 + Integer.toString(z) + "W";
                                    x++;
                                    y = y * -1;

                                    if (b.genomeIndex.containsKey(s2)) {
                                        gI = b.genomeIndex.get(s2);
                                    } else {
                                        if (b.genomeIndex.containsKey(s3)) {
                                            gI = b.genomeIndex.get(s3);
                                        }
                                    }
                                }
                            }

                            if (gI != 0 && gI != null) {

                                tableData[cnt][COL_GINDEX] = gI;
                            } else {
                                tableData[cnt][COL_GINDEX] = "";
                            }

                        } catch (Exception e) {
                        }
                    }

                    cnt++;
                }
            }
        }

        if (excl != null) {
            for (Integer I : excl.keySet()) {
                tableData[I.intValue()][COL_EXCLUDE] = excl.get(I);
            }

        }

        MyTableModel mtl = new MyTableModel();
        analysisTable.setModel(mtl);
        analysisTable.setAutoCreateRowSorter(true);
        sorter = new TableRowSorter<MyTableModel>(model);

        for (int i = 0; i < analysisTable.getModel().getColumnCount(); i++) {
            sorter.setComparator(i, (Comparator<?>) new EmptyRowComparator(sorter, i));
        }

        RowFilter<MyTableModel, Object> rf = new RowFilter<MyTableModel, Object>() {

            @Override
            public boolean include(Entry<? extends MyTableModel, ? extends Object> entry) {
                TreeSet t = (TreeSet) entry.getValue(COL_EXCLUDE);
                if (t == null || t.isEmpty() || !hideExcludedJCheckBox.isSelected()) {
                    return true;
                }

                return false;
            }
        };

        sorter.setRowFilter(rf);
        analysisTable.setRowSorter(sorter);
        sorter.addRowSorterListener(mrsl);

        TableColumnModel tcm = analysisTable.getColumnModel();

        for (int i = 0; i < tcm.getColumnCount(); i++) {
            switch (i) {
                case 0:
                case 1:
                case 2:
                    tcm.getColumn(i).setPreferredWidth(50);
                    break;
                default:
                    tcm.getColumn(i).setPreferredWidth(100);

            }
        }

        analysisTable.setComponentPopupMenu(dataTablePopupMenu);
        SelectionListener sl = new SelectionListener();
        analysisTable.getSelectionModel().addListSelectionListener(sl);
        analysisTable.getColumnModel().getSelectionModel().addListSelectionListener(sl);

        if (fileDate != null) {
            SimpleDateFormat dF = new SimpleDateFormat("EEE d MMM yyyy HH:mm:ss z");
            jLabel11.setText(dF.format(fileDate));
        }
    }

    public void setFileDate(Date date) {
        fileDate = date;
    }

    public boolean keepData(Double car, Double ear) {

        if (car == null || ear == null) {
            return false;
        }

        int opt = analysisSickFliterComboBox1.getSelectedIndex();

        if ((opt == 0 && car > sickCutOff) || (opt == 1 && ear > sickCutOff)
                || opt == 2 && car > sickCutOff && ear > sickCutOff) {
            return true;
        }

        return false;

    }

    public Double getAdjustedSpotSize(Double sz) {
        Double retval = sz;
        if (sz != null && sz < minSpotSize) {
            retval = minSpotSize;
        } else {
            if (sz != null && sz > maxSpotSize) {
                retval = maxSpotSize;
            }
        }
        return retval;
    }

    public class SelectionListener implements ListSelectionListener {

        @Override
        public void valueChanged(ListSelectionEvent e) {

            if (System.currentTimeMillis() - lastRefresh > 50) {
                updatePlots();
                lastRefresh = System.currentTimeMillis();
            }
        }
    }

    public class myRenderer extends DefaultTableCellRenderer {

        int r, c;

        public myRenderer(int row, int col) {
            super();
            r = row;
            c = col;
            setOpaque(true);
        }

        public void setAl(int al) {
            setHorizontalAlignment(al);
        }

        @Override
        public Component getTableCellRendererComponent(JTable table, Object value,
                boolean isSelected, boolean hasFocus, int row, int column) {

            try {
                super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

                int realRow = analysisTable.convertRowIndexToModel(row);
                String s = table.getModel().getValueAt(realRow, 1).toString();
                if (s == null) {
                    return this;
                }

                int col = analysisTable.convertColumnIndexToModel(column);

                switch (col) {
                    case 0:
                    case 1:
                    case 2:
                    case 3:
                        setHorizontalAlignment(CENTER);
                        break;
                    case 4:
                    case 5:
                        setHorizontalAlignment(LEFT);
                        break;
                    default:
                        setHorizontalAlignment(RIGHT);
                }

                if (isSelected) {
                    setForeground(Color.white);
                }

                try {
                    Hit hit = (Hit) analysisTable.getModel().getValueAt(realRow, COL_HIT);
                    if (hit instanceof Hit) {
                        switch (hit.i) {
                            case 1:
                                setBackground(new Color(100, 238, 100));
                                break;
                            case 2:
                                setBackground(new Color(238, 100, 100));
                        }
                    }
                } catch (Exception e) {
                    System.out.println(e.getLocalizedMessage());
                }


            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }

            return this;
        }

        @Override
        @SuppressWarnings("unchecked")
        public void setValue(Object value) {

            if (value == null) {
                return;
            }

            if (c == COL_INDEX) {
                setForeground(Color.white);
                setBackground(Color.black);
                setText("#");
            }

            if (value instanceof Double) {
                NumberFormat nf = NumberFormat.getNumberInstance();
                nf.setMaximumFractionDigits(4);
                setText(nf.format(value));
            } else if (value.getClass().equals(new TreeSet<String>().getClass())) {
                StringBuilder outString = new StringBuilder();

                for (String s : (TreeSet<String>) value) {
                    outString.append(s).append(", ");
                }

                if (outString.length() > 2) {
                    setText(outString.substring(0, outString.length() - 2));
                }
            } else {
                setText(value.toString());
            }

        }
    }

    class EmptyRowComparator implements Comparator<Object> {

        public final Object EMPTY_ROW = "";
        private final RowSorter<?> sorter;
        private final int column;

        public EmptyRowComparator(RowSorter<?> sorter, int column) {
            this.sorter = sorter;
            this.column = column;
        }

        @SuppressWarnings("unchecked")
        @Override
        public int compare(Object o1, Object o2) {
            Object orig1 = o1;
            Object orig2 = o2;
            if (o1.getClass().equals(new TreeSet<String>().getClass())) {
                o1 = o1.toString();
            }

            if (o2.getClass().equals(new TreeSet<String>().getClass())) {
                o2 = o2.toString();
            }

            if (o1.getClass().equals(new HitPair().getClass())) {
                o1 = ((HitPair) o1).a;
                o2 = ((HitPair) o2).a;
                if (((Integer) o1).intValue() == ((Integer) o2).intValue()) {
                    o1 = ((HitPair) orig1).b;
                    o2 = ((HitPair) orig2).b;
                }
            }

            if (o1.getClass().equals(new Hit().getClass())) {
                Integer i1 = ((Hit) o1).i;
                Integer i2 = ((Hit) o2).i;

                if (i1.intValue() == 0) {
                    o1 = EMPTY_ROW;
                } else {
                    o1 = i1;
                }

                if (i2.intValue() == 0) {
                    o2 = EMPTY_ROW;
                } else {
                    o2 = i2;
                }
            }

            if (o2.getClass().equals(new HitPair().getClass())) {
            }

            boolean empty1 = o1 == EMPTY_ROW;
            boolean empty2 = o2 == EMPTY_ROW;
            if (empty1 && empty2) {
                return 0;
            } else if (empty1) {
                return 1 * getSortOrder();
            } else if (empty2) {
                return -1 * getSortOrder();
            }
            return ((Comparable<Object>) o1).compareTo(o2);
        }

        private int getSortOrder() {
            SortOrder order = SortOrder.ASCENDING;
            for (SortKey sortKey : sorter.getSortKeys()) {
                if (sortKey.getColumn() == column) {
                    order = sortKey.getSortOrder();
                    break;
                }
            }
            return order == SortOrder.ASCENDING ? 1 : -1;
        }
    }
    public Object tableData[][];

    /**
     * @return the minSpotSize
     */
    public double getMinSpotSize() {
        return minSpotSize;
    }

    /**
     * @param minSpotSize the minSpotSize to set
     */
    public void setMinSpotSize(double minSpotSize) {
        this.minSpotSize = minSpotSize;
    }

    /**
     * @return the maxSpotSize
     */
    public double getMaxSpotSize() {
        return maxSpotSize;
    }

    /**
     * @param maxSpotSize the maxSpotSize to set
     */
    public void setMaxSpotSize(double maxSpotSize) {
        this.maxSpotSize = maxSpotSize;
    }

    /**
     * @return the sickCutOff
     */
    public double getSickCutOff() {
        return sickCutOff;
    }

    /**
     * @param sickCutOff the sickCutOff to set
     */
    public void setSickCutOff(double sickCutOff) {
        this.sickCutOff = sickCutOff;
    }

    /**
     * @return the lowCutOff
     */
    public double getLowCutOff() {
        return lowCutOff;
    }

    /**
     * @param lowCutOff the lowCutOff to set
     */
    public void setLowCutOff(double lowCutOff) {
        this.lowCutOff = lowCutOff;
    }

    /**
     * @return the highCutOff
     */
    public double getHighCutOff() {
        return highCutOff;
    }

    /**
     * @param highCutOff the highCutOff to set
     */
    public void setHighCutOff(double highCutOff) {
        this.highCutOff = highCutOff;
    }

    /**
     * @return the tableData
     */
    public Object[][] getTableData() {
        return tableData;
    }

    /**
     * @param tableData the tableData to set
     */
    public void setTableData(Object[][] tableData) {
        this.tableData = tableData;
    }

    /**
     * @return the analysisTable
     */
    public javax.swing.JTable getAnalysisTable() {
        return analysisTable;
    }

    /**
     * @param analysisTable the analysisTable to set
     */
    public void setAnalysisTable(javax.swing.JTable analysisTable) {
        this.analysisTable = analysisTable;
    }

    /**
     * @return the jScrollPane1
     */
    public javax.swing.JScrollPane getjScrollPane1() {
        return tableJScrollPane;
    }

    /**
     * @param jScrollPane1 the jScrollPane1 to set
     */
    /**
     * @return the sickFilterType
     */
    public int getSickFilterType() {
        return sickFilterType;
    }

    /**
     * @param sickFilterType the sickFilterType to set
     */
    public void setSickFilterType(int sickFilterType) {
        this.sickFilterType = sickFilterType;
    }

    class MyTableModel extends AbstractTableModel {

        public String[] columnNames = {"#", "Plate", "Row", "Col", "ORF", "Gene",
            "Ctrl", "Ctrl SD", "Exp", "Exp SD", "Ratio", " Ratio SD",
            "Ratio < p", "Ratio > q", "Diff", "p-value", "Hit?",
            "Exclude"};

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public int getRowCount() {
            return tableData.length;
        }

        @Override
        public String getColumnName(int col) {
            return columnNames[col];
        }

        @Override
        public Object getValueAt(int row, int col) {
            return tableData[row][col];
        }

        @Override
        public Class<?> getColumnClass(int c) {
            if (c == 9 || c == 7 || c == 5 || c == COL_HIT) {
                return Object.class;
            }

            if (getValueAt(0, c) != null) {
                if (c == COL_EXCLUDE) {
                    return TreeSet.class;
                }

                if (c == COL_RATIO || c == COL_PVAL) {
                    return Double.class;
                }

                return getValueAt(0, c).getClass();
            } else {
                return String.class;
            }
        }

        @Override
        public boolean isCellEditable(int row, int col) {
            return false;
        }
    }

    public void doFind(String s) {

        int row = analysisTable.getSelectedRow();
        if (row == -1) {
            row = 0;
        }

        boolean found = false;
        int i = row + 1;

        while (!found && i < analysisTable.getRowCount()) {
            String orf = "";
            String gene = "";
            try {
                orf = analysisTable.getValueAt(i, COL_ORF).toString().toLowerCase();
            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }

            try {
                gene = analysisTable.getValueAt(i, COL_GENE).toString().toLowerCase();
            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }

            if (orf.equals(s) || gene.equals(s)) {
                found = true;
            }

            i++;
        }

        if (found) {
            i--;
            analysisTable.setRowSelectionInterval(i, i);
//            setupSpotInfo(this);
            analysisTable.scrollRectToVisible(analysisTable.getCellRect(i, 0, true));
            return;
        } else {

            i = 0;
            while (!found && i < row) {
                String orf = "";
                String gene = "";
                try {
                    orf = analysisTable.getValueAt(i, COL_ORF).toString().toLowerCase();
                } catch (Exception e) {
                    System.out.println(e.getLocalizedMessage());
                }

                try {
                    gene = analysisTable.getValueAt(i, COL_GENE).toString().toLowerCase();
                } catch (Exception e) {
                    System.out.println(e.getLocalizedMessage());
                }

                if (orf.equals(s) || gene.equals(s)) {
                    found = true;
                }

                i++;
            }

            if (found) {
                i--;
                analysisTable.setRowSelectionInterval(i, i);
//                setupSpotInfo(this);
                analysisTable.scrollRectToVisible(analysisTable.getCellRect(i, 0, true));
                return;
            }
        }

        i = row + 1;
        while (!found && i < analysisTable.getRowCount()) {
            String orf = "";
            String gene = "";
            try {
                orf = analysisTable.getValueAt(i, COL_ORF).toString().toLowerCase();
            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }

            try {
                gene = analysisTable.getValueAt(i, COL_GENE).toString().toLowerCase();
            } catch (Exception e) {
                System.out.println(e.getLocalizedMessage());
            }

            if (orf.contains(s) || gene.contains(s)) {
                found = true;
            }

            i++;
        }

        if (found) {
            i--;
            analysisTable.setRowSelectionInterval(i, i);
//            setupSpotInfo(this);
            analysisTable.scrollRectToVisible(analysisTable.getCellRect(i, 0, true));
        } else {

            i = 0;
            while (!found && i < row) {
                String orf = "";
                String gene = "";
                try {
                    orf = analysisTable.getValueAt(i, COL_ORF).toString().toLowerCase();
                } catch (Exception e) {
                    System.out.println(e.getLocalizedMessage());
                }

                try {
                    gene = analysisTable.getValueAt(i, COL_GENE).toString().toLowerCase();
                } catch (Exception e) {
                    System.out.println(e.getLocalizedMessage());
                }

                if (orf.contains(s) || gene.contains(s)) {
                    found = true;
                }

                i++;
            }

            if (found == true) {
                i--;
                analysisTable.setRowSelectionInterval(i, i);
//                setupSpotInfo(this);
                analysisTable.scrollRectToVisible(analysisTable.getCellRect(i, 0, true));
            }
        }

    }

    @Override
    public String toString() {
        return getTitle();
    }

    public class MyRowSorterListener implements RowSorterListener {

        @Override
        public void sorterChanged(RowSorterEvent e) {

            for (int i = 0; i < analysisTable.getRowCount(); i++) {
                int j = analysisTable.convertRowIndexToModel(i);
                tableData[j][COL_INDEX] = i + 1;
            }

            for (spotInfo sI : spotInfos) {
                if (sI != null) {
                    updateSpotInfo(sI, analysisTable.convertRowIndexToView(sI.currRow));
                }
            }

            updatePlots();
        }
    }
    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuItem allJMenuItem;
    private javax.swing.JMenuItem allheadersJMenuItem;
    public javax.swing.JComboBox analysisSickFliterComboBox1;
    public javax.swing.JTable analysisTable;
    private javax.swing.JMenu clipCopyJMenu;
    private javax.swing.JPanel commandsPanel;
    public javax.swing.JMenu compareJMenu;
    public javax.swing.JPopupMenu dataTablePopupMenu;
    private javax.swing.JTextField descFilterJTextField;
    public javax.swing.JLabel dtNoSets;
    public javax.swing.JLabel dtScreenName;
    private javax.swing.JMenuItem excludeJMenuItem;
    private javax.swing.JButton exportTableJButton;
    private javax.swing.JPanel filteringPanel;
    private javax.swing.JMenuItem genesJMenuItem;
    public javax.swing.JComboBox hcHitsJComboBox;
    public javax.swing.JTextField hcpvalJTextField;
    public javax.swing.JCheckBox hideExcludedJCheckBox;
    public javax.swing.JTextField highCutOffJTextField;
    private javax.swing.JPanel highCutOffPanel;
    private javax.swing.JMenuItem includeJMenuItem;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel10;
    private javax.swing.JLabel jLabel11;
    private javax.swing.JLabel jLabel12;
    private javax.swing.JLabel jLabel13;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel25;
    private javax.swing.JLabel jLabel26;
    private javax.swing.JLabel jLabel28;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JLabel jLabel5;
    private javax.swing.JLabel jLabel6;
    private javax.swing.JLabel jLabel7;
    private javax.swing.JLabel jLabel8;
    private javax.swing.JLabel jLabel9;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JTextField jTextField1;
    public javax.swing.JComboBox lcHitsJComboBox;
    public javax.swing.JTextField lcpvalJTextField;
    private javax.swing.JButton linkageJButton;
    public javax.swing.JTextField linkageJTextField;
    public javax.swing.JTextField lowCutOffJTextField;
    private javax.swing.JPanel lowCutOffPanel;
    public javax.swing.JTextField maxSpotSizeTextField1;
    public javax.swing.JTextField minSpotSizeTextField1;
    private javax.swing.JMenuItem orfsJMenuItem;
    private javax.swing.JButton refreshTableJButton;
    private javax.swing.JButton saveButton;
    private javax.swing.JPanel screenInfoPanel;
    private javax.swing.JButton showPlotJButton;
    public javax.swing.JTextField sickCutOffTextField1;
    private javax.swing.JMenuItem spotInfoJMenuItem;
    private javax.swing.JPanel spotParamsPanel;
    private javax.swing.JScrollPane tableJScrollPane;
    private javax.swing.JPanel tableSettingsJPanel;
    // End of variables declaration//GEN-END:variables
}
